package com.gopay.checkorder.service.task;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.naming.CommunicationException;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.manager.BankOrderManager;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.cashier.BankCardType;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.domain.cps.vo.InAccInfo;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.DateUtils;
import com.gopay.common.util.FtpUtil;
import com.gopay.common.util.SendMail;
import com.gopay.common.util.SftpUtil;
import com.gopay.sms.client.GopaySMSHttpClient;
import com.gopay.sms.common.constants.SMSAppId;
import com.gopay.sms.common.domain.RequestVO;
import com.gopay.sms.common.domain.ResponseVO;

/**
 * 
 * @ClassName: PabDownloadOrderTaskImpl 
 * @Description: 平安快捷下载对账文件
 * @author ShenJun 
 * @date 2016年11月23日 下午2:28:41
 */
public class PabExpayDownloadOrderTaskImpl implements Task{
    private final static Logger logger = LoggerFactory.getLogger("CHECK_ORDER");
    
    @Resource(name = "pabExpayConfig")
    private Map<String, String> pabExpayConfig;
    
    @Resource(name = "cpsGeneralMainOrderQueryManager")
	protected CpsGeneralMainOrderQueryManager mainOrderQuery;
    
    @Resource(name = "bankOrderManager")
	protected BankOrderManager bankOrderManager;
    
    private int port = 22;
    
    private static final String SWITCH_ON = "on";

	@Resource(name = "smsConfig")
	private Map<String, String> smsConfig;
    
    
    @Override
    public void doTask() {
        logger.error("PabDownloadOrderTaskImpl: 定时任务start ");
        try {
            if ("off".equals(pabExpayConfig.get("mailSwitch"))) {
                logger.error("PabDownloadOrderTaskImpl: 不进行ftp操作直接返回!");
                return; 
            }
            String encoding = "UTF-8";
            String instId = pabExpayConfig.get("instId");
            String url = pabExpayConfig.get("ftp.url");
            String username = pabExpayConfig.get("ftp.username");
            String password = pabExpayConfig.get("ftp.password");
            String locpath = pabExpayConfig.get("ftp.locpath");
            String FTime = DateUtils.getYesterday();
//          String FPath = "upload";//测试环境对账文件路径
          String FPath = "expay";//生产环境对账文件路径
            //对账文件：[InstId]_FSP_[filetype]_[yyyyMMdd].txt，即：支付公司机构号_业务类型_文件类型_文件业务日期.txt
            String checkOrderFName = instId + "_FSP_CHK_" + FTime + ".txt";
            //checkOrderFName = "1248_FSP_CHK_20161208.txt";
            //String seriNo = DateUtils.getCurrDate("yyyyMMdd") + "0000001";//序号
            //退款结果文件：[InstId]_FSP_BRRF_[yyyyMMdd]_序号.txt，即：支付公司机构号_业务类型_文件类型_文件业务日期_序号.txt
            String refundFName = instId + "_FSP_BRRF_" + FTime + ".txt";//因为退款的文件名不确定，需要模糊查询，所以这里命名的时候不加.txt
            
            
            List sendFile = new ArrayList();
            List sendFileNames = new ArrayList();
            List checkOrderFiles = new ArrayList();
            List refundFiles = new ArrayList();
            
            String messageText = "";
            
            // 判断本地服务器是否存在平安快捷对账文件
            if (!(new File(locpath + checkOrderFName).exists())) {
                // 判断平安快捷对账文件是否存在
                if (SftpUtil.exist(url, port, username, password, 30000, FPath, checkOrderFName)) {
                    logger.error("PabDownloadOrderTaskImpl " + checkOrderFName + "exist!");
                    // 下载平安快捷对账文件
                    SftpUtil.download(url, port, username, password, 30000, FPath, checkOrderFName, (locpath.endsWith("/")?locpath:locpath+"/"));
                    logger.error("PabDownloadOrderTaskImpl " + checkOrderFName + " downLoad success!");
                    checkOrderFiles.add(checkOrderFName);
                }
            } else {
                logger.error("PabDownloadOrderTaskImpl local " + checkOrderFName + " 对账文件已成功下载, 不再进行ftp操作!");
            }
            
         // 判断本地服务器是否存在平安快捷退款结果文件
            if (!(new File(locpath + refundFName).exists())) {
                // 判断平安快捷退款结果文件是否存在
            	
                if (SftpUtil.existLikeName(url, port, username, password, 30000, FPath, refundFName)) {
                    logger.error("PabDownloadOrderTaskImpl " + refundFName + "exist!");
                    // 下载平安快捷退款结果文件
                    SftpUtil.downloadLikeName(url, port, username, password, 30000, FPath, refundFName, (locpath.endsWith("/")?locpath:locpath+"/"));
                    logger.error("PabDownloadOrderTaskImpl " + refundFName + " downLoad success!");
                    refundFiles.add(refundFName);
                    
                    //读取退款文件
//                    String localPath = locpath + refundFName;
//                    List<String> refundResultList = readFile(localPath, encoding);
                    //dealRefundResultList(refundResultList);
                }
            } else {
                logger.error("PabDownloadOrderTaskImpl local " + refundFName + "_BANKXXXX.txt 退款结果文件已成功下载, 不再进行ftp操作!");
            }
            
            // 若对账文件全部为空，则邮件内容标明
            if (checkOrderFiles.size() < 1) {
                logger.error("PabDownloadOrderTaskImpl: 平安快捷对账文件为null或本地已成功下载!");
                messageText += FTime + "平安快捷支付交易为空！";
            } else {
                messageText += FTime + ": 平安快捷对账文件见附件!" + checkOrderFName + "为: 本行交易记录";
                for (int i = 0; i < checkOrderFiles.size(); i++) {
                    sendFile.add(locpath + (String) checkOrderFiles.get(i));
                    sendFileNames.add((String) checkOrderFiles.get(i));
                }
            }
         // 若退款结果文件全部不为空，则邮件内容标明
            if (refundFiles.size() < 1) {
            	logger.error("PabDownloadOrderTaskImpl: 平安快捷退款对账文件为null或本地已成功下载!");
                messageText += FTime + "平安快捷退款交易为空！";
            } else{
            	messageText += FTime + ": 平安快捷退款结果文件见附件!" + refundFName + "为: 本行退款结果记录";
                for (int i = 0; i < refundFiles.size(); i++) {
                    sendFile.add(locpath + (String) refundFiles.get(i));
                    sendFileNames.add((String) refundFiles.get(i));
                }
            }
            if(sendFile.size() == 0){
            	return;
            }
            String subject = "平安快捷对账文件";
            String[] cc = pabExpayConfig.get("sendmail.cc").split(","); // 获取多个抄送人
            List ccList = Arrays.asList(cc);

            SendMail.sendMessage(pabExpayConfig.get("sendmail.host"), pabExpayConfig.get("sendmail.sender"),
                    pabExpayConfig.get("sendmail.username"), pabExpayConfig.get("sendmail.password"),
                    pabExpayConfig.get("sendmail.receiver"), subject, messageText, "text/html;charset=gb2312", ccList,
                    sendFile, sendFileNames);
            
        } catch (Exception e) {
            
        }
    }
    /**
     * 
     * @Description: 获取文件内容，返回一个list列表
     * @param path  全路径
     * @param encoding  编码格式
     * @return
     * @throws IOException 
     * @author ShenJun
     */
    private List<String> readFile(String path, String encoding) throws IOException {
    	List<String> list = new ArrayList<String>();
    	
    	FileInputStream fr = new FileInputStream(path);
		InputStreamReader is = new InputStreamReader(fr, encoding);
		BufferedReader br = new BufferedReader(is);
        while (br.ready()) {
        	list.add(br.readLine());
        }
		if (null != fr) {
			fr.close();
		}
		if (null != br) {
			br.close();
		}
        return list;
    }
    
    public void dealRefundResultList(List<String> refundResultList) throws CommunicationException, GopayException{
    	 //进行后续操作
        for (int i = 0; i < refundResultList.size(); i++) {
			if(i == 0){
				continue;//第一行是总信息，暂时不处理，5.00,1,5
			}
			dealRefundResult(refundResultList.get(i));
		}
    }
    
    /**
     * 
     * @Description: 处理退款结果数据
     * @param refundResult 
     * @author ShenJun
     * @throws GopayException 
     * @throws CommunicationException 
     */
    public void dealRefundResult(String refundResult) throws GopayException, CommunicationException{
    	//201306190000811,20130101 15:42:00,,0,1.00,156,201306180000007,,N,流水号重复
		//201306190000812,20130101 15:42:00,,0,5.00,156,201306180000009,,Y,
    	String []refundResultArray = refundResult.split(",");
//    	流水号（订单号）;	支付公司流水号
    	String serialNo = refundResultArray[0];
//    	交易日期;			YYYYMMDD HH:MM:SS
    	String orderDate = refundResultArray[1];
//    	银行卡号;			银行卡号或者银行卡Token号,如果是协议支付，该字段银行不返回
    	String signNo = refundResultArray[2];
//    	手续费
    	String around = refundResultArray[3]; 
//    	退货金额
    	String refundAmt = refundResultArray[4];
//    	交易货币代码
    	String currency = refundResultArray[5];
//    	原流水号；			批量退货文件中原流水号
    	String orgSerialNo = refundResultArray[6];
//    	原交易日期；		批量退货文件中原交易日期(YYYYMMDD)
    	String orgDate = refundResultArray[7];
//    	处理状态；			Y 成功；N 失败
    	String dealStatus = refundResultArray[8];
//    	失败原因；			如果处理状态为失败，则描述失败的原因。
    	String remark = refundResultArray[9];
    	
    	
    	CheckOrderResult checkOrderResult = new CheckOrderResult();
    	 checkOrderResult.setSuccess(true);
         InAccInfo accInfo = new InAccInfo();
         accInfo.setOrderId(serialNo);
         accInfo.setAmount(new BigDecimal(refundAmt));
         accInfo.setRetCode("00");
         accInfo.setCardType(BankCardType.Unknown.toString());
         checkOrderResult.setAccInfo(accInfo);
         checkOrderResult.setErrMsg(remark);
    	
    	BankOrder bankOrder = new BankOrder();
    	bankOrder.setOrderId(serialNo);
    	
    	if ("Y".equals(dealStatus)) {
			CpsGenMainOrder mainOrder = getMainOrder(serialNo);
            // 金额校验,跳过付款订单
            if (refundAmt.compareTo(mainOrder.getTotalOrderAmt().toString()) != 0) {
                logger.error("注意!!!金额不一致,bank = PAB,gopayOrderId = " + serialNo);
                sendSms4AmtInequality(serialNo);
            }
            logger.info("bank orderid: " + serialNo + ",银行退款结果金额一致校验成功");
			// 入账
			if (!bankOrderManager.inAcct(checkOrderResult)) {
				logger.info("bank orderid: " + serialNo + ",银行订单入账失败");
				// 入账不成功，对单失败
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				checkOrderResult.setErrMsg("enter account fail.");
				checkOrderResult.setSuccess(false);
				logger.error("bank orderid: " + serialNo + ",notify cashier failure!!!");
				bankOrderManager.updateEnterAccountFail(bankOrder);
			} else {
				logger.info("bank orderid: " + serialNo + ",入账成功更新银行订单");
				// 入账成功
				bankOrderManager.updateSuccess(bankOrder, BankOrderStatus.BANK_CALL_SUCCESS);
				checkOrderResult.setSuccess(true);
				logger.error("bank orderid: " + serialNo + ",notify cashier success!!!");
			}
		} else if ("N".equals(dealStatus)) {
			// 银行订单失败
			checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
			checkOrderResult.setErrMsg("enter bank fail.");

			checkOrderResult.setSuccess(false);
			logger.error("bank orderid: " + serialNo + ",bank return failure!!!");
			// 退款失败通知cashier入账 
			bankOrderManager.inAcct(checkOrderResult);
			bankOrder.setRemark2(checkOrderResult.getErrMsg()); // 记录失败原因
			// 入账失败,状态更新99
			bankOrderManager.updateFail(bankOrder);
		}
    }
    
	/**
	 * 获取订单信息
	 * 
	 * @param base
	 * @return
	 * @throws GopayException
	 */
	protected CpsGenMainOrder getMainOrder(String orderId) throws GopayException {
		// 获取主订单表
		CpsGenMainOrder mainOrder = mainOrderQuery.get(orderId);
		if (mainOrder == null) {
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E5041, "mainOrder is null");
		}

		return mainOrder;
	}
	
	/**
	 * 订单金额不一致,发送报警短信
	 * 
	 * @param gopayOrderId
	 */
	private void sendSms4AmtInequality(String orderId) {

		try {
			if (SWITCH_ON.equals(smsConfig.get("switch"))) {
				// 自定义短信内容，不提供验证码校验功能
				RequestVO req = new RequestVO();
				req.setAppId(SMSAppId._90000.value);
				req.setMobile(smsConfig.get("mobile"));// 电话号码(多个以逗号分隔)
				req.setContent(DateUtils.getCurrDate() + "订单金额不一致,bank:PAB,gopayOrderId:" + orderId);
				ResponseVO resp = GopaySMSHttpClient.getInstance().createVerificationCode(req);

				if (resp != null) {
					if ("100".equals(resp.getStatusCode())) {
						logger.error("[amt_inequality]订单金额不一致短信发送成功");
					} else {
						logger.error("[amt_inequality]订单金额不一致短信发送失败，原因：" + resp.getMessage());
					}
				}
			} else {
				logger.error("[amt_inequality] 订单金额不一致已关闭");

			}
		} catch (Exception e) {
			logger.error("[sentinel_sms]senSMS error: ", e);
		}

	}
    
    
    public static void main(String[] args) {
		String path = "F://1202_FSP_BRRF_20130616_201306190000015.txt";
		FileInputStream fr;
		try {
			fr = new FileInputStream(path);
			InputStreamReader is = new InputStreamReader(fr,"UTF-8");
			BufferedReader br = new BufferedReader(is);
	        StringBuffer sb = new StringBuffer();
	        while (br.ready()) {
	            //sb.append(br.readLine());
	            System.out.println(br.readLine());
	        }
	        
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
		
	}
}
class PabExpayDealRefundThread extends Thread{
	
}